const shell = require('shelljs');
const { getChangelog } = require('shipjs/src/helper');

const packages = JSON.parse(
  shell.exec('yarn run --silent lerna list --toposort --json', {
    silent: true,
  })
);
const changedPackages = packages
  .map((package) => ({
    ...package,
    isPublished: Boolean(
      shell.exec(`git tag -l ${package.name}@${package.version}`, {
        silent: true,
      }).stdout
    ),
  }))
  .filter(({ isPublished }) => !isPublished);

module.exports = {
  shouldPrepare: () => {
    return true;
  },
  getTagName: () =>
    changedPackages.map((package) => `${package.name}@${package.version}`),
  getStagingBranchName: () => `chore/release-${Date.now()}`,
  version({ exec }) {
    exec(
      'yarn lerna version --no-git-tag-version --no-push --exact --conventional-commits --yes'
    );

    return {
      // This version number is used for shouldPrepare.
      // for it to be useful, we need to chang shipjs to accept an array of nextVersions
      // @TODO: update this to packages.map(package => package.version) once it's supported in shipjs
      // see https://github.com/algolia/shipjs/issues/986
      nextVersion: packages[0].version,
    };
  },
  formatCommitMessage: () => `chore: release`,
  formatPullRequestTitle: () => `chore: release`,
  formatPullRequestMessage: ({
    repo,
    repoURL,
    stagingBranch,
    releaseType,
    publishCommands,
    title,
  }) => {
    const repoLink = `[${repo}](${repoURL})`;
    // this is assuming there's a single "previous" version, so can't be used with independent versioning.
    // const diffLink = `[\`${currentVersion}\` → \`${nextVersion}\`](${diffURL})`;
    const publishCommandsTable = `\`\`\`${publishCommands}\`\`\``;

    const mergeInstruction = `
When merging this pull request, you need to **Squash and merge** and make sure that the title starts with \`${title}\`.
<details>
<summary>See details</summary>

After that, a commit \`${title}\` will be added and you or your CI can run \`shipjs trigger\` to trigger the release based on the commit.
![Squash and merge](https://raw.githubusercontent.com/algolia/shipjs/v0.24.4/assets/squash-and-merge.png)
</details>
    `.trim();

    const message = `
This pull request prepares the following release:
| Repository | Branch | Update |
|---|---|---|
| ${repoLink} | ${stagingBranch} | ${releaseType} |

### Release Summary
This is going to be published with the following command:

${publishCommandsTable}

### Merging Instructions
${mergeInstruction}

---

_This pull request is automatically generated by [Ship.js](https://github.com/algolia/shipjs)_.
`.trim();
    return message;
  },
  pullRequestTeamReviewers: ['frontend-experiences-web'],
  buildCommand: () => 'NODE_ENV=production yarn build:ci',
  publishCommand: () => 'yarn lerna publish from-package --yes',
  beforeCommitChanges() {
    shell.exec('yarn run doctoc');
  },
  releases: {
    extractChangelog: ({ tagName }) => {
      const package = changedPackages.find(
        ({ name, version }) => tagName === `${name}@${version}`
      );
      if (!package) {
        return '';
      }

      return getChangelog({ version: package.version, dir: package.location });
    },
  },
  slack: {
    // disable slack notification for `prepared` lifecycle.
    // Ship.js will send slack message only for `releaseSuccess`.
    prepared: null,
    releaseSuccess: ({
      appName,
      tagName,
      latestCommitHash,
      latestCommitUrl,
      repoURL,
    }) => ({
      pretext: `:tada: Successfully released *${appName}*`,
      fields: [
        {
          title: 'Branch',
          value: 'master',
          short: true,
        },
        {
          title: 'Commit',
          value: `*<${latestCommitUrl}|${latestCommitHash}>*`,
          short: true,
        },
        {
          title: 'Versions',
          value: tagName,
        },
        {
          title: 'Releases',
          value: `${repoURL}/releases`,
        },
      ],
    }),
  },
};
